#include "course.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

// 全局课程数组
static Course courses[MAX_COURSES];
static int course_count = 0;

// 初始化课程管理器
void init_course_manager() {
    course_count = 0;
    memset(courses, 0, sizeof(courses));
    printf(" 课程管理器初始化完成\n");
}

// 验证课程编号格式
int validate_course_id(const char* id) {
    if (id == NULL || strlen(id) == 0 || strlen(id) >= MAX_ID_LEN) {
        return 0;
    }
    
    // 检查课程编号格式
    for (int i = 0; id[i] != '\0'; i++) {
        if (!isalnum(id[i]) && id[i] != '-' && id[i] != '_') {
            return 0;
        }
    }
    return 1;
}

// 检查课程是否存在
int is_course_exists(const char* id) {
    for (int i = 0; i < course_count; i++) {
        if (strcmp(courses[i].id, id) == 0) {
            return 1;
        }
    }
    return 0;
}

// 添加课程
int add_course(const char* id, const char* name, const char* type, 
               int hours, float credit, int max_enrollment) {
    if (!validate_course_id(id)) {
        printf(" 课程编号格式无效: %s\n", id);
        return 0;
    }
    
    if (is_course_exists(id)) {
        printf(" 课程编号已存在: %s\n", id);
        return 0;
    }
    
    if (course_count >= MAX_COURSES) {
        printf(" 课程数量已达上限(%d)\n", MAX_COURSES);
        return 0;
    }
    
    if (name == NULL || strlen(name) == 0) {
        printf(" 课程名称不能为空\n");
        return 0;
    }
    
    if (hours <= 0 || credit <= 0 || max_enrollment <= 0) {
        printf(" 学时、学分和最大选课人数必须大于0\n");
        return 0;
    }
    
    // 添加新课程
    Course* new_course = &courses[course_count];
    strncpy(new_course->id, id, MAX_ID_LEN - 1);
    strncpy(new_course->name, name, MAX_NAME_LEN - 1);
    strncpy(new_course->type, type, MAX_TYPE_LEN - 1);
    new_course->hours = hours;
    new_course->credit = credit;
    new_course->max_enrollment = max_enrollment;
    new_course->current_enrollment = 0;
    
    course_count++;
    printf("添加课程成功: %s - %s (%.1f学分)\n", id, name, credit);
    return 1;
}

// 删除课程
int delete_course(const char* id) {
    if (!validate_course_id(id)) {
        return 0;
    }
    
    for (int i = 0; i < course_count; i++) {
        if (strcmp(courses[i].id, id) == 0) {
            // 检查是否有学生选课
            if (courses[i].current_enrollment > 0) {
                printf(" 课程 %s 仍有 %d 名学生选课，无法删除\n", 
                       id, courses[i].current_enrollment);
                return 0;
            }
            
            // 将最后一个课程移到当前位置
            if (i < course_count - 1) {
                courses[i] = courses[course_count - 1];
            }
            course_count--;
            printf(" 删除课程成功: %s\n", id);
            return 1;
        }
    }
    
    printf(" 未找到课程: %s\n", id);
    return 0;
}

// 根据课程编号查找课程
Course* find_course_by_id(const char* id) {
    if (!validate_course_id(id)) {
        return NULL;
    }
    
    for (int i = 0; i < course_count; i++) {
        if (strcmp(courses[i].id, id) == 0) {
            return &courses[i];
        }
    }
    return NULL;
}

// 根据课程名称查找课程
Course* find_course_by_name(const char* name) {
    if (name == NULL || strlen(name) == 0) {
        return NULL;
    }
    
    for (int i = 0; i < course_count; i++) {
        if (strcmp(courses[i].name, name) == 0) {
            return &courses[i];
        }
    }
    return NULL;
}

// 更新课程信息
int update_course_info(const char* id, const char* new_name, 
                      const char* new_type, int new_hours, 
                      float new_credit, int new_max) {
    Course* course = find_course_by_id(id);
    if (course == NULL) {
        printf(" 未找到课程: %s\n", id);
        return 0;
    }
    
    if (new_name != NULL && strlen(new_name) > 0) {
        strncpy(course->name, new_name, MAX_NAME_LEN - 1);
    }
    
    if (new_type != NULL && strlen(new_type) > 0) {
        strncpy(course->type, new_type, MAX_TYPE_LEN - 1);
    }
    
    if (new_hours > 0) {
        course->hours = new_hours;
    }
    
    if (new_credit > 0) {
        course->credit = new_credit;
    }
    
    if (new_max > 0 && new_max >= course->current_enrollment) {
        course->max_enrollment = new_max;
    } else if (new_max > 0) {
        printf(" 最大选课人数不能小于当前选课人数(%d)\n", course->current_enrollment);
        return 0;
    }
    
    printf(" 更新课程信息成功: %s\n", id);
    return 1;
}

// 检查课程是否可以选课
int can_enroll(const char* course_id) {
    Course* course = find_course_by_id(course_id);
    if (course == NULL) {
        return 0;
    }
    
    return course->current_enrollment < course->max_enrollment;
}

// 获取课程学分
float get_course_credit(const char* course_id) {
    Course* course = find_course_by_id(course_id);
    if (course == NULL) {
        return 0.0;
    }
    
    return course->credit;
}

// 学生选课
int enroll_student_in_course(const char* course_id, const char* student_id) {
    Course* course = find_course_by_id(course_id);
    if (course == NULL) {
        printf(" 课程不存在: %s\n", course_id);
        return 0;
    }
    
    if (!can_enroll(course_id)) {
        printf(" 课程 %s 已满，无法选课\n", course_id);
        return 0;
    }
    
    // 检查学生是否已经选过该课程
    for (int i = 0; i < course->current_enrollment; i++) {
        if (strcmp(course->students[i], student_id) == 0) {
            printf(" 学生 %s 已经选过课程 %s\n", student_id, course_id);
            return 0;
        }
    }
    
    // 添加学生到课程
    strncpy(course->students[course->current_enrollment], student_id, MAX_ID_LEN - 1);
    course->current_enrollment++;
    
    printf(" 学生 %s 成功选课: %s\n", student_id, course_id);
    return 1;
}

// 学生退课
int remove_student_from_course(const char* course_id, const char* student_id) {
    Course* course = find_course_by_id(course_id);
    if (course == NULL) {
        printf(" 课程不存在: %s\n", course_id);
        return 0;
    }
    
    // 查找学生在课程中的位置
    int found_index = -1;
    for (int i = 0; i < course->current_enrollment; i++) {
        if (strcmp(course->students[i], student_id) == 0) {
            found_index = i;
            break;
        }
    }
    
    if (found_index == -1) {
        printf(" 学生 %s 未选课程 %s\n", student_id, course_id);
        return 0;
    }
    
    // 将最后一个学生移到当前位置
    if (found_index < course->current_enrollment - 1) {
        strcpy(course->students[found_index], 
               course->students[course->current_enrollment - 1]);
    }
    
    course->current_enrollment--;
    printf(" 学生 %s 成功退课: %s\n", student_id, course_id);
    return 1;
}

// 获取所有课程
Course* get_all_courses() {
    return courses;
}

// 获取课程数量
int get_course_count() {
    return course_count;
}

// 列出所有课程
void list_all_courses() {
    printf("\n=== 课程列表 (共%d门) ===\n", course_count);
    for (int i = 0; i < course_count; i++) {
        printf("%d. 编号: %s, 名称: %s, 性质: %s, 学时: %d, 学分: %.1f, 选课: %d/%d\n", 
               i + 1, courses[i].id, courses[i].name, courses[i].type,
               courses[i].hours, courses[i].credit, 
               courses[i].current_enrollment, courses[i].max_enrollment);
    }
}

// 课程管理菜单
void course_management_menu() {
    int choice;
    char id[MAX_ID_LEN], name[MAX_NAME_LEN], type[MAX_TYPE_LEN];
    int hours, max_enrollment;
    float credit;
    
    while (1) {
        printf("\n=== 课程信息管理 ===\n");
        printf("1. 添加课程\n");
        printf("2. 删除课程\n");
        printf("3. 修改课程信息\n");
        printf("4. 按编号查找\n");
        printf("5. 按名称查找\n");
        printf("6. 列出所有课程\n");
        printf("0. 返回主菜单\n");
        printf("请选择: ");
        
        scanf("%d", &choice);
        getchar(); // 清除换行符
        
        switch (choice) {
            case 1:
                printf("请输入课程编号: ");
                fgets(id, sizeof(id), stdin);
                id[strcspn(id, "\n")] = 0;
                
                printf("请输入课程名称: ");
                fgets(name, sizeof(name), stdin);
                name[strcspn(name, "\n")] = 0;
                
                printf("请输入课程性质: ");
                fgets(type, sizeof(type), stdin);
                type[strcspn(type, "\n")] = 0;
                
                printf("请输入授课学时: ");
                scanf("%d", &hours);
                
                printf("请输入学分: ");
                scanf("%f", &credit);
                
                printf("请输入最大选课人数: ");
                scanf("%d", &max_enrollment);
                getchar(); // 清除换行符
                
                if (add_course(id, name, type, hours, credit, max_enrollment)) {
                    log_operation("ADD_COURSE", id, name);
                }
                break;
                
            case 2:
                printf("请输入要删除的课程编号: ");
                fgets(id, sizeof(id), stdin);
                id[strcspn(id, "\n")] = 0;
                
                if (delete_course(id)) {
                    log_operation("DELETE_COURSE", id, "删除课程");
                }
                break;
                
            case 3:
                printf("请输入要修改的课程编号: ");
                fgets(id, sizeof(id), stdin);
                id[strcspn(id, "\n")] = 0;
                
                Course* course = find_course_by_id(id);
                if (course) {
                    printf("当前信息: %s - %s (%s, %d学时, %.1f学分, %d/%d人)\n",
                           course->id, course->name, course->type,
                           course->hours, course->credit,
                           course->current_enrollment, course->max_enrollment);
                    
                    printf("请输入新课程名称 (直接回车保持原值): ");
                    fgets(name, sizeof(name), stdin);
                    name[strcspn(name, "\n")] = 0;
                    
                    printf("请输入新课程性质 (直接回车保持原值): ");
                    fgets(type, sizeof(type), stdin);
                    type[strcspn(type, "\n")] = 0;
                    
                    printf("请输入新授课学时 (输入0保持原值): ");
                    scanf("%d", &hours);
                    
                    printf("请输入新学分 (输入0保持原值): ");
                    scanf("%f", &credit);
                    
                    printf("请输入新最大选课人数 (输入0保持原值): ");
                    scanf("%d", &max_enrollment);
                    getchar();
                    
                    if (update_course_info(id, 
                                          strlen(name) > 0 ? name : NULL,
                                          strlen(type) > 0 ? type : NULL,
                                          hours > 0 ? hours : 0,
                                          credit > 0 ? credit : 0,
                                          max_enrollment > 0 ? max_enrollment : 0)) {
                        log_operation("UPDATE_COURSE", id, "更新课程信息");
                    }
                } else {
                    printf("未找到课程编号为 %s 的课程\n", id);
                }
                break;
                
            case 4:
                printf("请输入要查找的课程编号: ");
                fgets(id, sizeof(id), stdin);
                id[strcspn(id, "\n")] = 0;
                
                course = find_course_by_id(id);
                if (course) {
                    printf("找到课程: 编号: %s, 名称: %s, 性质: %s, 学时: %d, 学分: %.1f, 选课: %d/%d\n",
                           course->id, course->name, course->type,
                           course->hours, course->credit,
                           course->current_enrollment, course->max_enrollment);
                } else {
                    printf("未找到课程编号为 %s 的课程\n", id);
                }
                break;
                
            case 5:
                printf("请输入要查找的课程名称: ");
                fgets(name, sizeof(name), stdin);
                name[strcspn(name, "\n")] = 0;
                
                course = find_course_by_name(name);
                if (course) {
                    printf("找到课程: 编号: %s, 名称: %s, 性质: %s, 学时: %d, 学分: %.1f, 选课: %d/%d\n",
                           course->id, course->name, course->type,
                           course->hours, course->credit,
                           course->current_enrollment, course->max_enrollment);
                } else {
                    printf("未找到课程名称为 %s 的课程\n", name);
                }
                break;
                
            case 6:
                list_all_courses();
                break;
                
            case 0:
                return;
                
            default:
                printf("无效选择，请重新输入\n");
        }
    }
}
